package com.ryujung.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

// 双线程交替打印1~100.一奇一偶
public class ThreadDemo1 {

    public static int num1 = 0;

    // synchronized + 双锁检查, 换成ReentrantLock也可以实现，注意lock.unlock
    private static void method1() {
        new Thread(() -> {
            while (ThreadDemo1.num1 < 100) {
                synchronized (ThreadDemo1.class) {
                    if (ThreadDemo1.num1 < 100 && ThreadDemo1.num1 % 2 == 1) {
                        System.out.println(Thread.currentThread().getName() + ":" + ++ThreadDemo1.num1);
                    }
                }
            }
        }).start();
        new Thread(() -> {
            while (ThreadDemo1.num1 < 100) {
                synchronized (ThreadDemo1.class) {
                    if (ThreadDemo1.num1 < 100 && ThreadDemo1.num1 % 2 == 0) {
                        System.out.println(Thread.currentThread().getName() + ":" + ++ThreadDemo1.num1);
                    }
                }
            }
        }).start();
    }

    public static volatile int num2 = 0;

    /**
     * 可重入锁 + condition 精确指定唤醒，实现双线程交替执行。
     */
    private static void method2() {
        ReentrantLock lock = new ReentrantLock();
        Condition cond1 = lock.newCondition();
        Condition cond2 = lock.newCondition();
        Thread t1 = new Thread(() -> {
            while (num2 < 100) {
                try {
                    lock.lock();
                    if (num2 < 100 && (num2 & 1) == 0) {
                        System.out.println(Thread.currentThread().getName() + ":" + ++num2);
                        cond2.signal();
                        cond1.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        });

        Thread t2 = new Thread(() -> {
            while (num2 < 100) {
                try {
                    lock.lock();
                    if (num2 < 100 && (num2 & 1) == 1) {
                        System.out.println(Thread.currentThread().getName() + ":" + ++num2);
                        cond1.signal();
                        cond2.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        });
        t1.start();
        t2.start();

    }

    static volatile boolean flag = true;
    static int i = 0;

    /**
     * volatile关键字 + 状态标志位  实现无锁，但是对性能耗费严重，并不推荐
     */
    private static void method3() {
        new Thread(() -> {

            while (i < 100) {
                if (flag) {
                    System.out.println(
                            Thread.currentThread().getName() + " : " + ++i);
                    flag = false;
                }
            }

        }).start();

        new Thread(() -> {

            while (i < 100) {
                if (!flag) {
                    System.out.println(
                            Thread.currentThread().getName() + " : " + ++i);
                    flag = true;
                }
            }

        }).start();
    }

    public static void main(String[] args) {
        // method1();
        // method2();
        method3();
    }

}
